// 材质
import * as THREE from 'three'

// 设置物体上所有材质的单双面
function setObjectMaterialSide(object: THREE.Object3D, side: THREE.Side) {
  object.traverse((_node) => {
    const node = _node as THREE.Mesh
    if (node.material) {
      const material = node.material as THREE.MeshStandardMaterial
      material.side = side
    }
  })
}

// 打散材质 - 为一个物体设置材质时，不会连带其他物体
function breakMaterials(object: THREE.Object3D) {
  object.traverse((_node) => {
    const node = _node as THREE.Mesh
    if (node.isMesh) {
      const material = node.material as THREE.MeshStandardMaterial
      node.material = material.clone()
    }
  })
}

// 染色：遍历一个节点树，为所有物体染色
const tintMaterialUuidColorMap: { [uuid: string]: number } = {} // 记录原有颜色
function tint(object: THREE.Object3D, color: number) {
  object.traverse((_node) => {
    const node = _node as THREE.Mesh
    if (node.isMesh) {
      const material = node.material as THREE.MeshStandardMaterial
      tintMaterialUuidColorMap[material.uuid] = material.color.toJSON()
      material.color.set(color)
    }
  })
}

// 取消染色
function untint(object: THREE.Object3D) {
  object.traverse((_node) => {
    const node = _node as THREE.Mesh
    if (node.isMesh) {
      const material = node.material as THREE.MeshStandardMaterial
      const color = tintMaterialUuidColorMap[material.uuid] || 0xffffff
      material.color.set(color)
    }
  })
}

// 禁用顶点颜色
function disableVertexColor(object: THREE.Object3D) {
  object.traverse((_node) => {
    const node = _node as THREE.Mesh
    if (node.isMesh) {
      const material = node.material as THREE.MeshStandardMaterial
      material.vertexColors = false
    }
  })
}

// 修复 FBX 转 GLB 后，材质的 transparent 属性变为 false 的问题
// 遍历所有 Mesh，检测到其alpha不为1的话，把transparent设置为true。
function fixFbxToGlbTransparent(root: THREE.Object3D) {
  root.traverse((_node) => {
    const node = _node as THREE.Mesh
    if (node.isMesh) {
      const material = node.material as THREE.MeshStandardMaterial
      if (material.opacity < 1 && material.transparent == false) {
        material.transparent = true
      }
    }
  })
}

// 导出
export { setObjectMaterialSide, breakMaterials, tint, untint, disableVertexColor, fixFbxToGlbTransparent }
